/*
 * @Author: WangLi
 * @Date: 2024-03-19 06:04:49
 * @LastEditors: WangLi
 * @LastEditTime: 2024-05-19 08:47:31
 */
import WPage from "../../common/WPage";
import { getUuid, writeBLECharacteristicValue, CODE_MESSAGE } from "../../utils/common";
import { getUser, getDevice, setDevice, setLastConnectedDevice } from "../../utils/storage";

const app = getApp();
function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
    return ("00" + bit.toString(16)).slice(-2);
  });
  return hexArr.join("");
}
WPage({
  data: {
    title: "附近的设备",
    devices: [],
    connected: false,
    bufferValue: "",
    deviceId: "",
    serviceId: "",
    characteristicId: "",
  },
  onLoad(options) {
    this.openBluetoothAdapter();
  },
  onShow() {
    this.openBluetoothAdapter();
  },
  onUnload() {
    this._discoveryStarted && this.stopBluetoothDevicesDiscovery();
  },
  openBluetoothAdapter() {
    if (!wx.openBluetoothAdapter) {
      wx.showModal({
        title: "提示",
        content: "当前微信版本过低，无法使用该功能，请升级到最新微信版本后重试。",
      });
      return;
    }
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log("openBluetoothAdapter success", res);
        this.startBluetoothDevicesDiscovery();
      },
      fail: (res) => {
        console.log("openBluetoothAdapter fail", res);
        if (res.errCode === 10001) {
          wx.showModal({
            title: "连接不成功",
            content: `请确定手机蓝牙已打开`,
            showCancel: false,
            confirmText: "好",
            success() {},
          });
          wx.onBluetoothAdapterStateChange((res) => {
            console.log("onBluetoothAdapterStateChange", res);
            if (res.available) {
              // 取消监听，否则stopBluetoothDevicesDiscovery后仍会继续触发onBluetoothAdapterStateChange，
              // 导致再次调用startBluetoothDevicesDiscovery
              wx.onBluetoothAdapterStateChange(() => {});
              this.startBluetoothDevicesDiscovery();
            }
          });
        }
      },
    });
  },
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return;
    }
    this._discoveryStarted = true;
    wx.startBluetoothDevicesDiscovery({
      success: (res) => {
        console.log("startBluetoothDevicesDiscovery success", res);
        this.onBluetoothDeviceFound();
      },
      fail: (res) => {
        console.log("startBluetoothDevicesDiscovery fail", res);
      },
    });
  },
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery({
      complete: () => {
        console.log("stopBluetoothDevicesDiscovery", this.data.devices);
        this._discoveryStarted = false;
      },
    });
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach((device) => {
        console.log("发现的蓝牙设备", device, device.localName, device.name);
        const deviceList = getDevice();
        const deviceIds = deviceList.map((item) => item.deviceId);
        if (deviceIds.includes(device.deviceId)) {
          return;
        }
        if (!device.name && !device.localName) {
          return;
        }
        const foundDevices = this.data.devices;
        const idx = inArray(foundDevices, "deviceId", device.deviceId);
        const data = {};
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device;
        } else {
          data[`devices[${idx}]`] = device;
        }
        this.setData(data);
      });
    });
  },
  createBLEConnection(e) {
    const deviceId = e.detail;
    const selectedDevice = this.data.devices.find((item) => item.deviceId === deviceId);
    const name = selectedDevice.name || selectedDevice.localName;
    this._createBLEConnection(deviceId, name);
  },
  _createBLEConnection(deviceId, name) {
    const _this = this;
    wx.showLoading({
      title: "连接中...",
    });
    wx.createBLEConnection({
      deviceId,
      success: () => {
        console.log("createBLEConnection success");
        wx.hideLoading();
        app.globalData.deviceId = deviceId;
        const deviceList = getDevice();
        const deviceData = { name, deviceId };
        deviceList.push(deviceData);
        setDevice(deviceList);
        setLastConnectedDevice(deviceData);
        this.setData({
          connected: true,
          name,
          deviceId,
        });
        this.checkUser();
        // this.getBLEDeviceServices(deviceId);
        this.stopBluetoothDevicesDiscovery();
        wx.showModal({
          title: "连接成功",
          content: `蓝牙设备“${name}”连接成功`,
          showCancel: false,
          confirmText: "好",
          success() {
            wx.redirectTo({ url: "/pages/functions/index" });
          },
        });
      },
      fail: (res) => {
        console.log("createBLEConnection fail", res);
        wx.hideLoading();
        this.setData({
          deviceId: "",
        });
        const errorMsg = CODE_MESSAGE[res.errCode];
        // const foundDevices = _this.data.devices;
        // const idx = inArray(foundDevices, "deviceId", deviceId);
        // if (idx !== -1) {
        //   foundDevices.splice(idx, 1);
        // }
        // console.log("_this.data.devices", _this.data.devices);
        // _this.setData({
        //   devices: _this.data.devices,
        // });
        wx.showModal({
          title: "连接不成功",
          content: `蓝牙设备“${name}”连接失败：${errorMsg}`,
          showCancel: false,
          confirmText: "好",
          success() {},
        });
      },
    });
  },
  closeBLEConnection() {
    const { deviceId } = this.data;
    wx.closeBLEConnection({
      deviceId,
    });
    this.setData({
      connected: false,
      canWrite: false,
      deviceId: "",
    });
  },
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.log("getBLEDeviceServices", res);
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
            return;
          }
        }
      },
    });
  },
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log("getBLEDeviceCharacteristics success", res.characteristics);
        // 这里会存在特征值是支持write，写入成功但是没有任何反应的情况
        // 只能一个个去试
        for (let i = 0; i < res.characteristics.length; i++) {
          const item = res.characteristics[i];
          if (item.properties.write) {
            this.setData({
              canWrite: true,
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            });
            break;
          }
        }
      },
      fail(res) {
        console.error("getBLEDeviceCharacteristics", res);
      },
    });
  },
  checkUser() {
    const userInfo = getUser();
    const { openid } = userInfo;
    const serviceId = getUuid("5508");
    writeBLECharacteristicValue(serviceId, getUuid("0083"), openid);
  },
});
